package com.soft.bams.service;

/**
 * @author yangwenqi
 * @decs TODO
 * @date 2025/4/18
 */
import com.soft.bams.dao.FileDao;
import com.soft.bams.dao.IDao;
import com.soft.bams.entity.*;
import com.soft.bams.vo.RankVO;
import com.soft.bams.exception.*;

import javax.security.auth.login.LoginException;
import javax.swing.*;
import java.util.List;
import java.util.TreeSet;

//方法:
//1. 用户开户(register)
//参数列表: Long 账号, String密码, String确认密码,String 姓名,String身份证号码,
// String邮箱,int 账户类型；
//(Long id, String password, String repassword, String name,
// String personID, String email, int type)
//返回类型：Account
//项目需求规定账户类型：0 – 储蓄账户  1 – 信用账户 2 – 可贷款储蓄账户 3– 可贷款信用账户
public class Bank {
    //关联
    private IDao<Account, List<Account>>dao;
    /*private IDao<Account, ArrayList<Account>>dao;*/
    //Bank单例模式
    private static Bank bank;
    public static Bank getInstance(){
        if(bank == null){
            bank = new Bank();
        }
        return bank;
    }
    public Bank(){
        dao = new FileDao();
    }

    public Account register(String password, String repassword,
                            String name, String personid, String email, int type)
            throws NotFoundException, RegisterException {
        // 1. 参数校验（完整化）
        if (password == null || repassword == null || password.isEmpty() || repassword.isEmpty()) {
            throw new NotFoundException("密码不能为空");
        }
        if (!password.equals(repassword)) {
            throw new RegisterException("两次输入的密码不一致");
        }
        if (name == null || name.isEmpty()) {
            throw new RegisterException("姓名不能为空");
        }
        if (personid == null || personid.isEmpty()) {
            throw new RegisterException("ID不能为空");
        }
        if (email == null || email.isEmpty()) {
            throw new RegisterException("邮箱不能为空");
        }

        // 2. 生成账户ID
        Long id = dao.createID();
        if (id == -1L) {
            throw new RegisterException("开户失败：ID生成失败");
        }

        // 3. 创建账户对象（覆盖所有 type 分支）
        Account account;
        switch (type) {
            case 0:
                account = new SavingAccount(id, password, name, personid, email, 0);
                break;
            case 1:
                account = new CreditAccount(id, password, name, personid, email, 0, 1000);
                break;
            case 2:
                account = new LoanSavingAccount(id, password, name, personid, email, 0, 0);
                break;
            case 3:
                account = new LoanCreditAccount(id, password, name, personid, email, 0, 1000, 0);
                break;
            default:
                throw new RegisterException("无效的账户类型：type = " + type);  // 替换 return null
        }
        dao.insert(account);
        /*JOptionPane.showMessageDialog(null, "开户成功！");*/  // 移除此行
        return account;
    }

    public Account login(Long id, String password) throws NotFoundException, LoginException {
        Account account=null;
        if(id==null ||password==null||password.equals(" ")){
//            System.out.println("用户ID和密码不能为空！");
//            return null;
            throw new NotFoundException("用户ID和密码不能为空！");
        }
        account=dao.selectOne(id, password);
        if(account!=null){
            System.out.println("登录成功！");
//            JOptionPane.showMessageDialog(null , "登录成功！");

        }else{
//            System.out.println("用户或密码错误！");
            throw new LoginException("用户或密码错误！");
        }
        return account;
    }

    public Account deposit(Long id, double money) throws NotFoundException, MoneyException {
        if(id==null){
//            System.out.println("用户名错误或输入的金额错误！");
//            return null;
            throw new NotFoundException("用户名不能为空");
        }
        if(money<=0){
//            System.out.println("金额不能<=0");
            throw new MoneyException("金额不能<=0");
        }
        Account account = dao.selectOne(id);
        if(account!=null){
            account.deposit(money);
            dao.update(account);
        }else{
//            System.out.println("该账户ID不存在！");
            throw new NotFoundException("该账户ID不存在！");
        }
        return account;
    }

    public Account withdraw(Long id, String password, double money)
            throws NotFoundException, MoneyException, BalanceNotEnoughException {
        if(id==null ||password==null||password.equals("")){
//            System.out.println("用户ID和密码不能为空,输入的金额不能<=0！");
//            return null;
            throw new NotFoundException("用户ID和密码不能为空");
        }
        if(money<=0){
            throw new MoneyException("输入的金额不能<=0");
        }
        Account account = dao.selectOne(id, password);
        if (account != null) {
            account.withdraw(money);
            dao.update(account);
        }else{
//            System.out.println("账户或密码错误！");
            throw new NotFoundException("账户或密码错误！");

        }
        return account;
    }


    public boolean transfer(Long from, String passwordFrom, Long to, double money) throws MoneyException, NotFoundException, TransferException, BalanceNotEnoughException {
        if(from==null ||to==null){
//            System.out.println("转入转出账户不能为空，转出金额不能<=0");
//            return false;
            throw new NotFoundException("转入转出账户不能为空！");
        }
        if(passwordFrom==null||passwordFrom.equals("")){
            throw new NotFoundException("密码不能为空！");
        }
        if(money<=0){
            throw new MoneyException("输入的金额不能<=0");
        }
        if(to.equals(from)){
//            System.out.println("转入和转出账户不能一样！");
//            return false;
            throw new TransferException("转入和转出账户不能一样!");
        }

        Account fromAcc = dao.selectOne(from, passwordFrom);
        Account toAcc = dao.selectOne(to);
        if (fromAcc != null && toAcc != null) {
            //因为贷款的额度已经加入余额里面所以不用再判断
            if((fromAcc instanceof SavingAccount)&&(fromAcc.getBalance()<money)){
//                System.out.println("余额不足！");
//                return false;
                throw new BalanceNotEnoughException("余额不足！");
            }
            if((fromAcc instanceof CreditAccount)&&(fromAcc.getBalance()+ ((CreditAccount) fromAcc).getCeiling()<money)){
//                System.out.println("余额不足！");
//                return false;
                throw new BalanceNotEnoughException("余额不足！");
            }
            fromAcc.withdraw(money);
            dao.update(fromAcc);
            toAcc.deposit(money);
            dao.update(toAcc);
            /*JOptionPane.showMessageDialog(null , "转账成功！");*/
//                System.out.println("转账成功！");
            return true;
        }
//        System.out.println("转出和转入账户要存在！");
//        return false;
        throw new NotFoundException("转出和转入账户不能为空！");
    }

    public double totalBalance() {
        double total = 0;
        for (Account a : dao.selectAll()) {
            if (a != null) {
                total += a.getBalance();
            }
        }
        return total;
    }


    public double totalCeiling() {
        double total = 0;
        for (Account a : dao.selectAll()) {
            if (a != null) {
                if (a instanceof CreditAccount) {
                    total += ((CreditAccount) a).getCeiling();
                }
            }
        }
        return total;
    }

    public Account updateCeling(Long id, double money, String password) throws MoneyException, NotFoundException, TypeException {
        if(id==null ||password==null||password.equals("")){
//            System.out.println("用户ID和密码不能为空,输入的金额不能<=0！");
//            return null;
            throw new NotFoundException("用户ID和密码不能为空");
        }
        if(money<=0){
            throw new MoneyException("输入的金额不能<=0！");
        }
        Account account = dao.selectOne(id, password);
        if (account != null) {
            if(account instanceof CreditAccount){
                ((CreditAccount) account).setCeiling(money);
                dao.update(account);
            }else{
//                System.out.println("您的银行卡不支持透支额度的更新！");
                throw new TypeException("您的银行卡不支持透支额度的更新！");
            }
        }else{
//            System.out.println("账户或密码错误！");
            throw new NotFoundException("账户或密码错误！");
        }
        return account;
    }
    //贷款
    public Account requestLoan(double money,Long id) throws MoneyException, NotFoundException, TypeException {
        if(id==null ){
//            System.out.println("用户ID不能为空,贷款金额不能<=0！");
//            return null;
            throw new NotFoundException("用户ID不能为空");
        }
        if(money<=0){
            throw new MoneyException("贷款金额不能<=0！");
        }
        Account account = dao.selectOne(id);
        if (account != null) {
            if(account instanceof Loanable){
                ((Loanable) account).requestLoan(money);
                dao.update(account);
            }else{
//                System.out.println("请选择可以的贷款账户！");
                throw new TypeException("请选择可以的贷款账户！");
            }
        }
        return account;
    }
    //还贷款
    public Account payLoan(double money,Long id) throws TypeException, NotFoundException, MoneyException {
        if(id==null){
//            System.out.println("用户ID不能为空,贷款金额不能<=0！");
//            return null;
            throw new NotFoundException("用户ID不能为空");
        }
        if(money<=0){
            throw new MoneyException("贷款金额不能<=0！");
        }
        Account account = dao.selectOne(id);
        if (account != null) {
            if(account instanceof Loanable){
                ((Loanable) account).payLoan(money);
                dao.update(account);
            }else{
//                System.out.println("该账户不支持还贷！");
                throw new TypeException("该账户不支持还贷！");
            }
        }
        return account;
    }
    public long totalLoan(){
        long total = 0;
        for (Account a : dao.selectAll()) {
            if (a != null) {
                if (a instanceof LoanCreditAccount) {
                    total+=((LoanCreditAccount)a).getLoanAmount();
                }else if(a instanceof LoanSavingAccount){
                    total+=((LoanSavingAccount)a).getLoanAmount();
                }
            }
        }
        return total;
    }
    public TreeSet<RankVO> rank(){
        TreeSet<RankVO> set = new TreeSet<>();
        for (Account a : dao.selectAll()) {
            if(a!=null){
                String personId = a.getPersonid();
                String name = a.getName();
                double total = totalBalanceByPersonId(personId);
                RankVO rankVO = new RankVO(personId , name , total);
                set.add(rankVO);
            }
        }
        return set;
    }

    //所有账户的总资产
    private double totalBalanceByPersonId(String personId) {
        double sum = 0.0;
        for (Account a : dao.selectAll()) {
            if(a!=null && a.getPersonid().equals(personId)){
                sum += a.getBalance();
            }
        }
        return sum;
    }
}

